package com.letv.core.utils;

import java.lang.reflect.Method;

/**
 * 通过反射得到API中MediaMetadataRetriever类的引用，
 * 此类在android3.0以上系统，可以获得到视频文件的meta值，例如分辨率，码流，视频长度等。
 * 请参加Android API中 MediaMetadataRetriever类
 * @author liuheyuan
 *
 */
public class LetvMediaMetadataRetriever {

	/*
	 * Do not change these metadata key values without updating their
	 * counterparts in include/media/mediametadataretriever.h!
	 */
	/**
	 * The metadata key to retrieve the numberic string describing the order of
	 * the audio data source on its original recording.
	 */
	public static final int METADATA_KEY_CD_TRACK_NUMBER = 0;
	/**
	 * The metadata key to retrieve the information about the album title of the
	 * data source.
	 */
	public static final int METADATA_KEY_ALBUM = 1;
	/**
	 * The metadata key to retrieve the information about the artist of the data
	 * source.
	 */
	public static final int METADATA_KEY_ARTIST = 2;
	/**
	 * The metadata key to retrieve the information about the author of the data
	 * source.
	 */
	public static final int METADATA_KEY_AUTHOR = 3;
	/**
	 * The metadata key to retrieve the information about the composer of the
	 * data source.
	 */
	public static final int METADATA_KEY_COMPOSER = 4;
	/**
	 * The metadata key to retrieve the date when the data source was created or
	 * modified.
	 */
	public static final int METADATA_KEY_DATE = 5;
	/**
	 * The metadata key to retrieve the content type or genre of the data
	 * source.
	 */
	public static final int METADATA_KEY_GENRE = 6;
	/**
	 * The metadata key to retrieve the data source title.
	 */
	public static final int METADATA_KEY_TITLE = 7;
	/**
	 * The metadata key to retrieve the year when the data source was created or
	 * modified.
	 */
	public static final int METADATA_KEY_YEAR = 8;
	/**
	 * The metadata key to retrieve the playback duration of the data source.
	 */
	public static final int METADATA_KEY_DURATION = 9;
	/**
	 * The metadata key to retrieve the number of tracks, such as audio, video,
	 * text, in the data source, such as a mp4 or 3gpp file.
	 */
	public static final int METADATA_KEY_NUM_TRACKS = 10;
	/**
	 * The metadata key to retrieve the information of the writer (such as
	 * lyricist) of the data source.
	 */
	public static final int METADATA_KEY_WRITER = 11;
	/**
	 * The metadata key to retrieve the mime type of the data source. Some
	 * example mime types include: "video/mp4", "audio/mp4", "audio/amr-wb",
	 * etc.
	 */
	public static final int METADATA_KEY_MIMETYPE = 12;
	/**
	 * The metadata key to retrieve the information about the performers or
	 * artist associated with the data source.
	 */
	public static final int METADATA_KEY_ALBUMARTIST = 13;
	/**
	 * The metadata key to retrieve the numberic string that describes which
	 * part of a set the audio data source comes from.
	 */
	public static final int METADATA_KEY_DISC_NUMBER = 14;
	/**
	 * The metadata key to retrieve the music album compilation status.
	 */
	public static final int METADATA_KEY_COMPILATION = 15;
	/**
	 * If this key exists the media contains audio content.
	 */
	public static final int METADATA_KEY_HAS_AUDIO = 16;
	/**
	 * If this key exists the media contains video content.
	 */
	public static final int METADATA_KEY_HAS_VIDEO = 17;
	/**
	 * If the media contains video, this key retrieves its width.
	 */
	public static final int METADATA_KEY_VIDEO_WIDTH = 18;
	/**
	 * If the media contains video, this key retrieves its height.
	 */
	public static final int METADATA_KEY_VIDEO_HEIGHT = 19;
	/**
	 * This key retrieves the average bitrate (in bits/sec), if available.
	 */
	public static final int METADATA_KEY_BITRATE = 20;
	/**
	 * This key retrieves the language code of text tracks, if available. If
	 * multiple text tracks present, the return value will look like: "eng:chi"
	 * 
	 * @hide
	 */
	public static final int METADATA_KEY_TIMED_TEXT_LANGUAGES = 21;
	/**
	 * If this key exists the media is drm-protected.
	 * 
	 * @hide
	 */
	public static final int METADATA_KEY_IS_DRM = 22;
	/**
	 * This key retrieves the location information, if available. The location
	 * should be specified according to ISO-6709 standard, under a mp4/3gp box
	 * "@xyz". Location with longitude of -90 degrees and latitude of 180
	 * degrees will be retrieved as "-90.0000+180.0000", for instance.
	 */
	public static final int METADATA_KEY_LOCATION = 23;

	private Class<Object> MediaMetadataRetriever = null;

	private Object mInstanceObject = null;

	private Method SetDataSource = null;

	private Method ExtractMetadata = null;

	@SuppressWarnings("unchecked")
	private void getMediaMetadataRetriever() {

		try {
			MediaMetadataRetriever = (Class<Object>) Class.forName("android.media.MediaMetadataRetriever");
			mInstanceObject = MediaMetadataRetriever.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void getSetDataSource() {
		if (null == MediaMetadataRetriever) {
			getMediaMetadataRetriever();
		}

		if (null != MediaMetadataRetriever && null != mInstanceObject) {
			try {
				SetDataSource = MediaMetadataRetriever.getMethod("setDataSource", String.class);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private void getExtractMetadata() {
		if (null == MediaMetadataRetriever) {
			getMediaMetadataRetriever();
		}

		if (null != MediaMetadataRetriever && null != mInstanceObject) {
			try {
				ExtractMetadata = MediaMetadataRetriever.getMethod("extractMetadata", int.class);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 设置地址
	 * 
	 * @param path
	 */
	public void setDataSource(String path) {
		getSetDataSource();
		getExtractMetadata();
		if (null != SetDataSource) {
			try {
				SetDataSource.invoke(mInstanceObject, path);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 获得媒体文件时长
	 * 
	 * @param path
	 * @return
	 */
	public long getFileDuration() {
		Object d = null;

		if (null != ExtractMetadata) {
			try {
				d = ExtractMetadata.invoke(mInstanceObject, METADATA_KEY_DURATION);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		if (null != d) {
			String ds = (String) d;
			if (null != ds && !"".equals(ds)) {
				return Long.parseLong(ds);
			}
		}

		return 0;

	}

	/**
	 * 获得视频信息
	 * 
	 * @param key
	 * @return
	 */
	public String getVideoMetaData(int key) {
		String w = null;

		if (null != ExtractMetadata) {
			try {
				w = (String) ExtractMetadata.invoke(mInstanceObject, key);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return w;

	}

	/**
	 * 获得视频宽高
	 * 
	 * @return
	 */
	public String getVideo_W_H() {
		String w = getVideoMetaData(METADATA_KEY_VIDEO_WIDTH);
		String h = getVideoMetaData(METADATA_KEY_VIDEO_HEIGHT);
		if (w == null || h == null || "".equals(w) || "".equals(h)) {
			return "";
		} else {
			return w + "*" + h;
		}
	}

}
